<?php

//+!
namespace TwinPeaks\Core
//+!
{

const OPT_NO_ACCESS_CONTROLL = 1;
const OPT_DISABLE_REQUEST_DISPATCH = 2;
const OPT_RETURN_CONTROLLER_RESULT = 3;

/**
 * @param string $input
 * @param integer $mod
 * @return integer
 */
function NumericHash($input, $mod)
{
	$md5_hash = md5($input);
	$sum = 0;
	for ($i = 0; $i < 32 /* 128-bits */; $i++)
	{
		$sum += ord($md5_hash[$i]);
	}
	return $sum % $mod;
}

/**
 * @return string
 */
function get_unique_string($len = 12)
{
	$alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
	$alphabet_len = strlen($alphabet);
	$string = '';
	
	for ($i = 0; $i < $len; $i++)
		$string .= $alphabet[mt_rand(0, $alphabet_len - 1)];
	
	return $string;
}

/**
 * @return string
 */
function get_unique_id($len = 12)
{
	return get_unique_string($len);
}

// Any not null value would break invocation cascade
const BREAK_CASCADE = true;

/**
 * @return mixed
 */
function cascade_invoc($obj_list, $method_name, $args = [])
{
	foreach ($obj_list as $obj)
	{
		if (method_exists($obj, $method_name))
			if (($result = call_user_func_array([$obj, $method_name], $args)) !== null)
				return $result;	
	}
	return null;
}

/**
 * @return array
 */
function cascade_invoc_no_break($obj_list, $method_name, $args = [])
{
	$result = [];
	foreach ($obj_list as $obj)
		if (method_exists($obj, $method_name))
			$result[]= call_user_func_array([$obj, $method_name], $args);
	
	return $result;
}

/**
 * @return string
 */
function get_class_method_name($string)
{
	$parts = explode('::', $string);
	return count($parts) == 1 ? $string : $parts[1];
}

/**
 * @param string $class Class name
 * @return string
 */
function getUnqualifiedClassName($class, &$namespace = null)
{
	$pos = strrpos($class, '\\');
	if ($pos === false)
	{
		$namespace = '';
		return $class;
	}
	else
	{
		$namespace = ($pos == 0) ? '' : substr($class, 0, $pos - strlen($class));
		if ($namespace[0] == '\\')
			$namespace = substr($namespace, 1);
		return substr($class, $pos + 1);
	}
}

/**
 * @return boolean
 */
function isFQCN($class)
{
	return ($class && $class[0] == '\\') ? true : false;
}

//+!
}// End of TwinPeaks\Core
//+!

//+!
// See http://www.ietf.org/rfc/rfc2616.txt
namespace TwinPeaks\Core\Http
//+!
{
	
const HTTP_PROTOCOL_TOKEN = 'http';
const HTTPS_PROTOCOL_TOKEN = 'https';

/**
* Types of HTTP request
*/
const GET_METHOD = 1;
const POST_METHOD = 2;
const OPTIONS_METHOD = 4;
const PUT_METHOD = 8;
const DELETE_METHOD = 16;
const TRACE_METHOD = 32;
const CONNECT_METHOD = 64;
const HEAD_METHOD = 128;

/**
 * HTTP request tokens
 */
const OPTIONS_TOKEN = 'OPTIONS';
const GET_TOKEN = 'GET';
const POST_TOKEN = 'POST';
const PUT_TOKEN = 'PUT';
const DELETE_TOKEN = 'DELETE';
const TRACE_TOKEN = 'TRACE';
const CONNECT_TOKEN = 'CONNECT';

/**
 * Tokens of request header fields
 */
const REQFIELD_ACCEPT = 'Accept';
const REQFIELD_ACCEPT_CHARSET = 'Accept-Charset';
const REQFIELD_ACCEPT_ENCODING = 'Accept-Encoding';
const REQFIELD_ACCEPT_LANGUAGE = 'Accept-Language';
const REQFIELD_AUTHORIZATION = 'Authorization';
const REQFIELD_EXPECT = 'Expect';
const REQFIELD_FROM = 'From';
const REQFIELD_HOST = 'Host';
const REQFIELD_IF_MATCH = 'If-Match';
const REQFIELD_IF_MODIFIED_SINCE = 'If-Modified-Since';
const REQFIELD_IF_NONE_MATCH = 'If-None-Match';
const REQFIELD_IF_RANGE = 'If-Range';
const REQFIELD_IF_UNMODIFIED_SINCE = 'If-Unmodified-Since';
const REQFIELD_MAX_FORWARDS = 'Max-Forwards';
const REQFIELD_PROXY_AUTHORIZATION = 'Proxy-Authorization';
const REQFIELD_RANGE = 'Range';
const REQFIELD_REFERER = 'Referer';
const REQFIELD_TE = 'TE';
const REQFIELD_USER_AGENT = 'User-Agent';

const RESHF_CONTENT_TYPE = 'Content-Type';

const STATUS_CODE_BAD_REQUEST = 400;
const STATUS_CODE_NOT_FOUND = 404;

const MIME_TYPE_APPLICATION_JSON = 'application/json';

//+!
}// End of TwinPeaks\Core\Http
//+!
